package com.wuye.basic.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.wuye.basic.domain.*;
import com.wuye.basic.domain.cascade.CascadeBalcony;
import com.wuye.basic.domain.cascade.CascadeCommunity;
import com.wuye.basic.domain.cascade.CascadeHome;
import com.wuye.basic.domain.cascade.CascsadeUnit;
import com.wuye.basic.domain.dto.WyUnitInfoDTO;
import com.wuye.basic.service.WyBalconyunithomeService;
import com.wuye.common.constant.HttpStatus;
import com.wuye.common.core.page.PageDomain;
import com.wuye.common.core.page.TableDataInfo;
import com.wuye.common.core.page.TableSupport;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wuye.basic.mapper.WyUnitInfoMapper;
import com.wuye.basic.service.IWyUnitInfoService;

/**
 * 单元Service业务层处理
 * 
 * @author avalon
 * @date 2024-11-26
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class WyUnitInfoServiceImpl extends ServiceImpl<WyUnitInfoMapper,WyUnitInfo>
        implements IWyUnitInfoService
{

    private final WyUnitInfoMapper wyUnitInfoMapper;
    private final WyBalconyunithomeService wyBalconyunithomeService;


    /**
     * 查询单元列表
     * 
     * @param wyUnitInfo 单元
     * @return 单元
     */
    @Override
    public List<WyUnitInfo> selectWyUnitInfoList(WyUnitInfo wyUnitInfo)
    {
        return wyUnitInfoMapper.selectWyUnitInfoList(wyUnitInfo);
    }


    @Override
    public TableDataInfo selectInfo(WyUnitInfo wyUnitInfo) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Page<WyBalconyunithome> page = Page.of(pageDomain.getPageNum(), pageDomain.getPageSize());
        Page<WyBalconyunithome> wyBalconyunithomePage = Db.lambdaQuery(WyBalconyunithome.class)
                .eq(wyUnitInfo.getBalconyId() != null, WyBalconyunithome::getBalconyid, wyUnitInfo.getBalconyId())
                .eq(wyUnitInfo.getUnitId() != null, WyBalconyunithome::getUnitid, wyUnitInfo.getUnitId())
                .isNull(WyBalconyunithome::getHomeid)
                .orderBy(true,false,WyBalconyunithome::getId)
                .page(page);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(
                wyBalconyunithomePage.getRecords().stream()
                        .map(
                                item -> WyUnitInfo.builder()
                                        .id(item.getId())
                                        .balconyId(item.getBalconyid())
                                        .unitId(item.getUnitid())
                                        .communityId(
                                                Db.lambdaQuery(WyBalcony.class)
                                                        .eq(WyBalcony::getBalconyId, item.getBalconyid())
                                                        .one().getCommunityId()
                                        )
                                        .unitName(
                                                Db.lambdaQuery(WyBalcony.class)
                                                        .eq(WyBalcony::getBalconyId, item.getBalconyid())
                                                        .one().getBalconyName() +
                                                        Db.lambdaQuery(WyUnit.class)
                                                                .eq(WyUnit::getUnitId, item.getUnitid())
                                                                .one().getUnitName()
                                        )
                                        .unitLayserNumber(
                                                Db.lambdaQuery(WyBalcony.class)
                                                        .eq(WyBalcony::getBalconyId, item.getBalconyid())
                                                        .one().getLayserNumber()
                                        )
                                        .homeNumber(
                                                Db.lambdaQuery(WyBalconyunithome.class)
                                                        .eq(WyBalconyunithome::getBalconyid,item.getBalconyid())
                                                        .eq(WyBalconyunithome::getUnitid,item.getUnitid())
                                                        .isNotNull(WyBalconyunithome::getHomeid)
                                                        .count()
                                        )
                                        .build()
                        ).collect(Collectors.toList())
        );
        rspData.setTotal(
                wyBalconyunithomePage.getTotal()
        );
        return rspData;
    }

    @Override
    public boolean deleteBatchIds(List<Long> list) {
        List<WyBalconyunithome> listed = Db.lambdaQuery(WyBalconyunithome.class)
                .in(WyBalconyunithome::getId, list)
                .list();
        listed.forEach(
                item -> wyBalconyunithomeService.removeBatchByIds(
                        Db.lambdaQuery(WyBalconyunithome.class)
                                .eq(WyBalconyunithome::getBalconyid,item.getBalconyid())
                                .eq(WyBalconyunithome::getUnitid,item.getUnitid())
                                .list()
                                .stream().map(WyBalconyunithome::getId).collect(Collectors.toList())
                )
        );
        return true;
    }

    @Override
    public WyUnitInfoDTO getInfoById(Long id) {
        WyBalconyunithome wyBalconyunithome = Db.lambdaQuery(WyBalconyunithome.class)
                .eq(WyBalconyunithome::getId, id)
                .isNull(WyBalconyunithome::getHomeid)
                .one();
        if (Objects.isNull(wyBalconyunithome)) {
            return null;
        }
        WyUnitInfo wyUnitInfo = WyUnitInfo.builder()
                .id(id)
                .unitId(wyBalconyunithome.getUnitid())
                .balconyId(wyBalconyunithome.getBalconyid())
                .communityId(
                        Db.lambdaQuery(WyBalcony.class)
                                .eq(WyBalcony::getBalconyId, wyBalconyunithome.getBalconyid())
                                .one().getCommunityId()
                )
                .unitName(
                        Db.lambdaQuery(WyBalcony.class)
                                .eq(WyBalcony::getBalconyId, wyBalconyunithome.getBalconyid())
                                .one().getBalconyName() +
                                Db.lambdaQuery(WyUnit.class)
                                        .eq(WyUnit::getUnitId, wyBalconyunithome.getUnitid())
                                        .one().getUnitName()
                )
                .unitLayserNumber(
                        Db.lambdaQuery(WyBalcony.class)
                                .eq(WyBalcony::getBalconyId, wyBalconyunithome.getBalconyid())
                                .one().getLayserNumber()
                )
                .homeNumber(
                        Db.lambdaQuery(WyBalconyunithome.class)
                                .eq(WyBalconyunithome::getBalconyid, wyBalconyunithome.getBalconyid())
                                .eq(WyBalconyunithome::getUnitid, wyBalconyunithome.getUnitid())
                                .isNotNull(WyBalconyunithome::getHomeid)
                                .count()
                )
                .build();
        WyUnitInfoDTO wyUnitInfoDTO = BeanUtil.copyProperties(wyUnitInfo, WyUnitInfoDTO.class);
        wyUnitInfoDTO.setHomeIds(
                Db.lambdaQuery(WyBalconyunithome.class)
                        .eq(WyBalconyunithome::getBalconyid,wyUnitInfoDTO.getBalconyId())
                        .eq(WyBalconyunithome::getUnitid,wyUnitInfoDTO.getUnitId())
                        .isNotNull(WyBalconyunithome::getHomeid)
                        .list().stream().map(WyBalconyunithome::getHomeid).collect(Collectors.toList())
        );
        return wyUnitInfoDTO;
    }

    @Override
    public boolean edit(WyUnitInfoDTO wyUnitInfoDTO) {
        WyBalconyunithome wyBalconyunithome = Db.lambdaQuery(WyBalconyunithome.class)
                .eq(WyBalconyunithome::getId, wyUnitInfoDTO.getId())
                .isNull(WyBalconyunithome::getHomeid)
                .one();
        if (Objects.isNull(wyBalconyunithome)) {
            return false;
        }
        List<Long> oldHomeIds = Db.lambdaQuery(WyBalconyunithome.class)
                .eq(WyBalconyunithome::getBalconyid, wyBalconyunithome.getBalconyid())
                .eq(WyBalconyunithome::getUnitid, wyUnitInfoDTO.getUnitId())
                .isNotNull(WyBalconyunithome::getHomeid)
                .list().stream().map(WyBalconyunithome::getHomeid).collect(Collectors.toList());

        List<Long> newHomeIds = wyUnitInfoDTO.getHomeIds();

        List<Long> addHomeIds = newHomeIds.stream()
                .filter(item -> !oldHomeIds.contains(item))
                .collect(Collectors.toList());

        List<Long> delHomeIds = oldHomeIds.stream()
                .filter(item -> !newHomeIds.contains(item))
                .collect(Collectors.toList());

        if (!delHomeIds.isEmpty()){
            wyBalconyunithomeService.removeBatchByIds(
                    Db.lambdaQuery(WyBalconyunithome.class)
                            .eq(WyBalconyunithome::getBalconyid,wyBalconyunithome.getBalconyid())
                            .eq(WyBalconyunithome::getUnitid,wyBalconyunithome.getUnitid())
                            .in(WyBalconyunithome::getHomeid,delHomeIds)
                            .list().stream()
                            .map(WyBalconyunithome::getId)
                            .collect(Collectors.toList())
            );
        }


        List<WyBalconyunithome> addList = new ArrayList<>();
        addHomeIds.forEach(
                item -> addList.add(
                        WyBalconyunithome
                                .builder()
                                .balconyid(wyBalconyunithome.getBalconyid())
                                .unitid(wyUnitInfoDTO.getUnitId())
                                .homeid(item)
                                .build()
                )
        );
        return wyBalconyunithomeService.saveBatch(addList);
    }

    @Override
    public List<CascadeCommunity> cascade() {

        List<WyCommunity> wyCommunityList = Db.lambdaQuery(WyCommunity.class)
                .select(WyCommunity::getCommunityId, WyCommunity::getCommunityName)
                .list();

        List<WyBalcony> wyBalconyList = Db.lambdaQuery(WyBalcony.class)
                .select(WyBalcony::getBalconyId, WyBalcony::getBalconyName, WyBalcony::getCommunityId)
                .list();

        List<WyBalconyunithome> wyBalconyunithomeList = Db.lambdaQuery(WyBalconyunithome.class)
                .isNull(WyBalconyunithome::getHomeid)
                .list();

//        List<WyHome> wyHomeList = Db.lambdaQuery(WyHome.class)
//                .select(WyHome::getHomeId, WyHome::getHomeNumber, WyHome::getOwnerId)
//                .list();
//
//        List<Long> collect = Db.lambdaQuery(WyBalconyunithome.class)
//                .isNotNull(WyBalconyunithome::getHomeid)
//                .list().stream().map(WyBalconyunithome::getHomeid).distinct().collect(Collectors.toList());


        Map<Long, List<CascadeBalcony>> balconyMap  = wyBalconyList.stream()
                .collect(Collectors.groupingBy(
                        WyBalcony::getCommunityId, Collectors.mapping(
                                item -> CascadeBalcony.builder()
                                        .value(item.getBalconyId())
                                        .label(item.getBalconyName())
                                        .build(), Collectors.toList()
                        )
                ));

        Map<Long, List<CascsadeUnit>> unitMap = wyBalconyunithomeList.stream()
                .collect(Collectors.groupingBy(
                        WyBalconyunithome::getBalconyid, Collectors.mapping(
                                item -> CascsadeUnit.builder()
                                        .value(item.getUnitid())
                                        .label(Db.lambdaQuery(WyUnit.class)
                                                .eq(WyUnit::getUnitId, item.getUnitid())
                                                .one().getUnitName())
                                        .build(), Collectors.toList()
                        )
                ));

//        Map<Long, List<CascadeHome>> homeMap = wyHomeList.stream()
//                .filter(item -> !collect.contains(item.getHomeId()))
//                .collect(Collectors.groupingBy(
//                        , Collectors.mapping(
//                                item -> CascadeHome.builder()
//                                        .id(item.getHomeId())
//                                        .homeInfo(item.getHomeNumber() + "[业主:" +
//                                                Db.lambdaQuery(WyOwner.class)
//                                                        .eq(WyOwner::getOwnerId, item.getHomeId())
//                                                        .one().getOwnerName()
//                                                + "]")
//                                        .build(), Collectors.toList()
//                        )
//                ));


        return  wyCommunityList.stream()
                .map(item -> {
                    List<CascadeBalcony> cascadeBalconyList = balconyMap.getOrDefault(item.getCommunityId(), Collections.emptyList());
                    cascadeBalconyList.forEach(
                            balcony -> {
                                List<CascsadeUnit> cascsadeUnitList = unitMap.getOrDefault(balcony.getValue(), Collections.emptyList());
//                                cascsadeUnitList.forEach(
//                                        unit -> {
//                                            List<CascadeHome> cascadeHomeList = homeMap.getOrDefault(unit.getId(), Collections.emptyList());
//                                            unit.setList(cascadeHomeList);
//                                        }
//                                );
                                  balcony.setChildren(cascsadeUnitList);
                            }
                    );
                    return CascadeCommunity.builder()
                            .value(item.getCommunityId())
                            .label(item.getCommunityName())
                            .children(cascadeBalconyList)
                            .build();
                }).collect(Collectors.toList());


//        List<CascadeCommunity> cascadeCommunityList = wyCommunityList.stream()
//                .map(
//                        item -> CascadeCommunity.builder()
//                                .id(item.getCommunityId())
//                                .communityName(item.getCommunityName())
//                                .list(balconyMap.getOrDefault(item.getCommunityId(),Collections.emptyList()))
//                                .build()
//                ).collect(Collectors.toList());
//        return cascadeCommunityList;
//        List<CascadeBalcony> cascadeBalconyList = new ArrayList<>();
//
//        wyCommunityList.forEach(
//                item -> Db.lambdaQuery(WyBalcony.class)
//                        .eq(WyBalcony::getCommunityId,item.getCommunityId())
//                        .list().forEach(
//                                ass -> cascadeBalconyList.add(
//                                        CascadeBalcony.builder()
//                                                .id(ass.getBalconyId())
//                                                .balconyName(ass.getBalconyName())
//                                                .build()
//                                )
//        ));
//
//        wyCommunityList.forEach(
//                item -> cascadeCommunityList.add(
//                        CascadeCommunity.builder()
//                                .id(item.getCommunityId())
//                                .CommunityName(item.getCommunityName())
//                                .list(cascadeBalconyList)
//                                .build()
//                )
//        );
//
//        wyBalconyList.forEach(
//                item ->  cascadeBalconyList.add(
//                        CascadeBalcony.builder()
//                                .id(item.getBalconyId())
//                                .balconyName(item.getBalconyName())
//                                .build()
//                )
//        );
//
//        List<WyHome> wyHomes = Db.lambdaQuery(WyHome.class)
//                .select(WyHome::getHomeId, WyHome::getHomeNumber, WyHome::getOwnerId)
//                .list();
//        List<CascadeHome> cascadeHomeList = new ArrayList<>();
//        wyHomes.forEach(
//                item -> cascadeHomeList.add(
//                        CascadeHome.builder()
//                                .id(item.getHomeId())
//                                .homeInfo(
//                                        item.getHomeNumber()+"["+
//                                                Db.lambdaQuery(WyOwner.class)
//                                                        .eq(WyOwner::getOwnerId, item.getOwnerId())
//                                                        .one().getOwnerName()
//                                                +"]"
//                                )
//                                .build()
//                )
//        );
//
//        List<WyUnit> wyUnits = Db.lambdaQuery(WyUnit.class)
//                .select(WyUnit::getUnitId, WyUnit::getUnitName).list();
//        List<CascsadeUnit> cascsadeUnitList = new ArrayList<>();
//        wyUnits.forEach(
//                item -> cascsadeUnitList.add(
//                        CascsadeUnit.builder()
//                                .id(item.getUnitId())
//                                .unitName(item.getUnitName())
//                                .list(cascadeHomeList)
//                                .build()
//                )
//        );
//

    }
}
